package com.basker.pisces.logger;

import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.StringUtils;

import com.basker.pisces.core.resource.IResourceLoader;
import com.basker.pisces.core.resource.annotation.ResouceLoader;

import ch.qos.logback.classic.LoggerContext;

@ResouceLoader(priority = Integer.MAX_VALUE, locationPatterns = {"classpath*:**/logback/*.properties"})
public class LogBackProperetiesConfigResourceLoader implements IResourceLoader, InitializingBean {
    private static final String LOG_PATH = "log.path";
    /**
     * 内置的文本资源
     */
    private Set<String> buildInResources;

    @Autowired
    private ResourcePatternResolver resolver;

    @Autowired
    private LogBackPropertyConfigLoader logBackPropertyConfigLoader;

    @Autowired(required = false)
    private ConfigurableEnvironment envioment;

    @Override
    public void afterPropertiesSet() throws Exception {
        this.putSpringProperties();
        this.setDefaultLogPathProperty();
        this.loadBuildInResources();

    }

    @Override
    public void load(Resource[] resources) throws IOException {
        if (buildInResources != null) {
            resources = Stream.of(resources).filter(rs -> !buildInResources.contains(rs.toString()))
                    .toArray(s -> new Resource[s]);
        }

        for (Resource resource : resources) {
            this.logBackPropertyConfigLoader.load(resource);
        }
    }

    private void loadBuildInResources() throws IOException {
        Resource[] resources = resolver.getResources("classpath*:**/*pisces*logback*.properties");

        if (resources.length > 0) {
            for (Resource resource : resources) {
                this.logBackPropertyConfigLoader.load(resource);
            }

            this.buildInResources = Stream.of(resources).map(s -> s.toString()).collect(Collectors.toSet());
        }
    }

    private void putSpringProperties() {
        if (envioment == null) {
            return;
        }

        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();

        MutablePropertySources propertySources = envioment.getPropertySources();
        Iterator<PropertySource<?>> iterator = propertySources.iterator();

        while (iterator.hasNext()) {
            PropertySource<?> source = iterator.next();

            if (source instanceof MapPropertySource) {
                String[] propertyNames = ((MapPropertySource) source).getPropertyNames();

                for (String key : propertyNames) {
                    Object val = source.getProperty(key);
                    if (val instanceof String) {
                        loggerContext.putProperty(key, (String) val);
                    }
                }
            }
        }

    }

    private void setDefaultLogPathProperty() {
        if (envioment == null) {
            return;
        }

        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();

        String logPath = loggerContext.getProperty(LOG_PATH);
        if (StringUtils.isEmpty(logPath)) {
            loggerContext.putProperty(LOG_PATH, envioment.getProperty("user.home") + "/logs/");
        }
    }

}
